/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
#include "Group.hpp"
#include "Machine.hpp"
//#include "Core.hpp"
#include "MuRoMainFrame.h"

using namespace MuRo;

CGroup::CGroup(std::string name, MuRoMainFrame *MuRo, wxTreeCtrl *treeCtrl, wxTreeItemId item)
  :name(name), MuRo(MuRo), treeCtrl(treeCtrl), item(item), isSelected(false)
{
  
}

CGroup::~CGroup()
{
  for (groupIter gi=groups.begin(); gi!=groups.end(); gi++)
  {
    delete (gi->second);
  }
  for (machineIter mi=machines.begin(); mi!=machines.end(); mi++)
  {
    delete (mi->second);
  }
}

CMachine* CGroup::findMachine(std::string MaCIGroup, bool createNew)
{
  std::string::size_type firstDot=MaCIGroup.find_first_of(".",0);
  if (firstDot!=std::string::npos)
  {
    
    CGroup *group;
    std::string groupName=MaCIGroup.substr(0,firstDot); //the first segment of the group
    std::string subGroupName=MaCIGroup.substr(firstDot+1); //the rest of the group name
    groupIter i=groups.find(groupName);
    if (i!=groups.end())
    {
      group=i->second;
    } else if (createNew) {
      wxTreeItemId ti=treeCtrl->AppendItem(item, groupName);
      dPrint(1,"Creating group %s",groupName.c_str());
      group=new CGroup(groupName, MuRo, treeCtrl, ti);
      AddGroup(group);
    } else {
      return NULL;
    }
    
    return group->findMachine(subGroupName, createNew);
    
  } else {
    CMachine *machine=NULL;
    machineIter i=machines.find(MaCIGroup);
    if (i!=machines.end())
    {
      //machine exists
      if (!createNew)
      {
        machine=i->second;
      } else {
        machine=NULL;
      }
    } else if (createNew) {
      //create machine
      machine=new CMachine(MaCIGroup, MuRo);
      wxTreeItemId ti=treeCtrl->AppendItem(item, MaCIGroup,-1,-1, new CGroupTreeItemData(machine));
      machine->SetTreeItem(ti);
      dPrint(1,"Creating machine %s",MaCIGroup.c_str());
      AddMachine(machine);
    }
    
    return machine;
  }
}

CMachine* CGroup::CreateMachine(std::string MaCIGroup)
{
  return findMachine(MaCIGroup, true);
}

CMachine* CGroup::FindMachine(std::string MaCIGroup)
{
  return findMachine(MaCIGroup, false);
}

bool CGroup::AddGroup(CGroup *group)
{
  std::pair<groupIter, bool> p= groups.insert(
      std::pair<std::string, CGroup*>(group->GetName(),group) );
  return p.second;
}

bool CGroup::AddMachine(CMachine *machine)
{
  std::pair<machineIter, bool> p= machines.insert(
      std::pair<std::string, CMachine*>(machine->GetName(),machine) );
  return p.second;
}

void CGroup::Select(bool select)
{
  isSelected=select;
  for (groupIter gi=groups.begin(); gi!=groups.end(); gi++)
  {
    gi->second->Select(select);
  }
  for (machineIter mi=machines.begin(); mi!=machines.end(); mi++)
  {
    mi->second->Select(select);
  }
}

std::string CGroup::GetName()
{
  return name;
}
